package cn.t.facade.order;


import cn.t.constants.ParamConstants;
import cn.t.constants.ResponseError;
import cn.t.converter.order.OrderModelConverter;
import cn.t.core.exception.BizException;
import cn.t.dto.order.DislodgeOrderDTO;
import cn.t.enums.order.ErrorTypeEnum;
import cn.t.enums.order.OrderTransferStatusEnum;
import cn.t.enums.order.OrderTypeEnum;
import cn.t.model.device.DeviceDO;
import cn.t.model.order.ExceptionLogDO;
import cn.t.model.order.OrderDO;
import cn.t.model.order.OrderDetailDO;
import cn.t.model.user.CustomerFirmDO;
import cn.t.model.user.UserQueryDO;
import cn.t.service.device.DeviceService;
import cn.t.service.order.ExceptionLogService;
import cn.t.service.order.OrderDetailService;
import cn.t.service.order.OrderService;
import cn.t.service.user.CustomerFirmService;
import cn.t.service.user.UserQueryService;
import cn.t.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author l
 */
@Slf4j
@Service
public class CommonOrderFacade  {

    public DislodgeOrderDTO getDislodgeOrderDTO(String orderSn) {
        OrderDO orderRequest = new OrderDO();
        orderRequest.setOrderSn(orderSn);
        OrderDO orderDo = orderService.findInfoByModel(orderRequest);
        if (ObjectUtils.isEmpty(orderDo)) {
            throw new BizException(ResponseError.ORDER_NOT_EXIST, String.format(ResponseError.ORDER_NOT_EXIST.getName(), orderSn));
        }
        DeviceDO deviceDO = deviceService.findById(orderDo.getDeviceId());

        if (orderDo.getUserId() != null) {
            UserQueryDO userQueryDO1 = new UserQueryDO();
            userQueryDO1.setId(orderDo.getUserId());
            UserQueryDO userQueryDO  = userQueryService.findUserByFirmId(userQueryDO1).stream().findFirst().orElse(null);
            //主信息
            return OrderModelConverter.converterDislodgeMain(orderDo, userQueryDO, deviceDO);
        }
        throw new BizException(ResponseError.ORDER_NOT_EXIST, String.format(ResponseError.ORDER_NOT_EXIST.getName(), orderSn));

    }


    /**
     * 请求参数处理
     * @return
     */
    public List<OrderDetailDO> exportPageList(OrderDetailDO orderDetailDO) {
        List<String> orderSnList = orderDetailDO.getOrderSnList();
        int totalPages = OrderModelConverter.getTotalPages(orderDetailDO.getOrderSnList(), ParamConstants.PAGE_MAX_SIZE);
        List<OrderDetailDO> orderDetails = new ArrayList<>();
        for (int i = 0; i < totalPages; i++) {
            // 使用stream API切片列表
            List<String> orderNos = orderSnList.stream()
                    .skip((long) i *  ParamConstants.PAGE_MAX_SIZE)
                    .limit( ParamConstants.PAGE_MAX_SIZE)
                    .collect(Collectors.toList());
            orderDetailDO.setOrderSnList(orderNos);
            List<OrderDetailDO> orderGoods = orderDetailService.queryListByOrderSn(orderDetailDO);
            orderDetails.addAll(orderGoods);
            if (orderDetails.size()>=ParamConstants.EXPORTPAGEMAXSIZE){
                break;
            }
        }
        return orderDetails.subList(0, Math.min(orderDetails.size(), ParamConstants.EXPORTPAGEMAXSIZE));
    }
    /**
     * 数据处理
     *
     * @param beans
     * @param type 1:订单列表 2:异常订单列表
     * @return
     */
    public List<DislodgeOrderDTO> getList(List<OrderDO> beans, OrderTypeEnum type) {
        if (CollectionUtils.isEmpty(beans)) {
            return new ArrayList<>();
        }
        List<Long> deviceList = beans.stream().map(OrderDO::getDeviceId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        List<Long> transferUserIdList = beans.stream().map(OrderDO::getTransferUserId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        List<String> orderNos = beans.stream().map(OrderDO::getOrderSn).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        //deviceList
        Map<Long, DeviceDO> deviceBeanMap = new HashMap<>();
        if (deviceList.size() > 0) {
            deviceBeanMap = deviceService.
                    getDeviceList(null, null,deviceList).stream().collect(Collectors.toMap(DeviceDO::getId, Function.identity()));
        }

        Map<String,List<ExceptionLogDO>> exceptionLogMap=new HashMap<>();
        //填充异常内容
        if (OrderTypeEnum.ERRORDER_TYPE.equals(type)){
            exceptionLogMap=exceptionLogService.queryListByNo(orderNos).stream().collect(Collectors.groupingBy(ExceptionLogDO::getOrderSn));
        }
        Map<Long, UserQueryDO> transferUserIdMap=new HashMap<>();

        //填充转单记录信息
        if (OrderTypeEnum.TRANSFER_ORDER.equals(type) && !CollectionUtils.isEmpty(transferUserIdList)){
            UserQueryDO userQueryDO = new UserQueryDO();
            userQueryDO.setIds(transferUserIdList);
            transferUserIdMap = userQueryService.findUserByFirmId(userQueryDO).stream().collect(Collectors.toMap(UserQueryDO::getId, Function.identity()));
        }
        List<Long> firmIds = beans.stream().map(OrderDO::getFirmId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        Map<Long, CustomerFirmDO> firmIdNameMap = new HashMap<>();
        if (firmIds.size() > 0) {
            firmIdNameMap = this.customerFirmService.getFirmInfoMap(firmIds);
        }
        Map<Long, CustomerFirmDO> finalFirmIdNameMap = firmIdNameMap;
        Map<Long, DeviceDO> finalDeviceBeanMap = deviceBeanMap;
        Map<String, List<ExceptionLogDO>> finalExceptionLogMap = exceptionLogMap;
        //转人信息
        Map<Long, UserQueryDO> finalTransferUserIdMap = transferUserIdMap;
        return beans.stream().map(n -> {
           DeviceDO deviceBean = finalDeviceBeanMap.get(n.getDeviceId());
           List<ExceptionLogDO> exceptionLogs = finalExceptionLogMap.get(n.getOrderSn());
           UserQueryDO userQueryDO = finalTransferUserIdMap.get(n.getTransferUserId());
            CustomerFirmDO firmDO = finalFirmIdNameMap.get(n.getFirmId());
            DislodgeOrderDTO listResp=   OrderModelConverter.convertBeanToDTO(n, deviceBean);
           if (ObjectUtils.isNotEmpty(exceptionLogs)) {
               String result = IntStream.range(0, exceptionLogs.size())
                       .mapToObj(i -> String.format("%d.%s", i + 1, ErrorTypeEnum.getDescByKey(exceptionLogs.get(i).getExceptionType())))
                       .collect(Collectors.joining(" "));
               listResp.setExceptionTypeName(result);
           }
           if (userQueryDO!=null){
               listResp.setTransferAdminName(userQueryDO.getUserName());
           }
            listResp.setGmtTransfer(DateUtil.setTime(n.getGmtTransfer()));

            listResp.setOrderTransferStatus(n.getOrderTransferStatus());
           listResp.setOrderTransferStatusName(
                   OrderTransferStatusEnum.getDescByKey(n.getOrderTransferStatus()));
            listResp.setFirmId(n.getFirmId());
            if (firmDO!=null){
                listResp.setFirmCode(firmDO.getFirmCode());
                listResp.setFirmName(firmDO.getFirmName());
            }

            return listResp;
        }).collect(Collectors.toList());
    }

    @Resource
    private ExceptionLogService exceptionLogService;
    @Resource
    private UserQueryService userQueryService;
    @Resource
    private CustomerFirmService customerFirmService;
    @Resource
    private DeviceService deviceService;
    @Resource
    private OrderService orderService;
    @Resource
    private OrderDetailService orderDetailService;
}
